<template>
  <q-page class="flex flex-top">
    <q-toolbar class="absolute-top" style="width: 100%">
      <q-breadcrumbs
        class="text-grey-8"
        active-color="blank"
        style="font-size: 16px; width: 100%"
      >
        <q-breadcrumbs-el
          label="根目录"
          icon="home"
          class="clickable"
          @click="
            () => {
              resourcePath.resourceId = null;
              getResource();
            }
          "
        />
        <q-breadcrumbs-el
          :label="item.name"
          class="clickable"
          v-for="item in resourcePath.path"
          :key="item.id"
          @click="IntoResource(item)"
        />
      </q-breadcrumbs>

      <q-space />

      <q-btn
        icon="refresh"
        ref="RefreshBtnRef"
        color="primary"
        flat
        rounded
        v-close-popup
        @click="reload"
      ></q-btn>

      <q-btn
        icon="fa-solid fa-blog"
        color="primary"
        flat
        rounded
        size="sm"
        v-close-popup
      >
        <q-popup-edit auto-save v-slot="scope">
          <q-banner
            ><q-input
              label="博客名称"
              v-model="scope.value"
              autofocus
              @keyup.enter="CreateBlog(scope)"
              maxlength="20"
            >
              <q-btn flat @click="CreateBlog(scope)" v-close-popup>
                <q-icon name="share" />
              </q-btn> </q-input
          ></q-banner>
        </q-popup-edit>
      </q-btn>

      <q-btn icon="upload" color="primary" flat rounded>
        <q-popup-edit auto-save v-slot="scope">
          <q-file
            label="选择文件(最大200MB) *"
            @update:model-value="
              (val) => {
                CreateFile(val, scope);
              }
            "
            filled
            dense
            counter
            max-files="1"
            multiple
            style="max-width: 300px"
            :max-total-size="1024 * 1024 * 200"
          >
            <template v-slot:prepend>
              <q-icon name="attach_file" />
            </template>
          </q-file>
        </q-popup-edit>
      </q-btn>
      <q-btn icon="folder" color="primary" flat rounded>
        <q-popup-edit auto-save v-slot="scope">
          <q-banner
            ><q-input
              label="新建文件夹名称"
              v-model="scope.value"
              autofocus
              @keyup.enter="CreateDir(scope)"
              maxlength="20"
            >
              <q-btn flat @click="CreateDir(scope)" v-close-popup>
                <q-icon name="fa-solid fa-folder-plus" />
              </q-btn> </q-input
          ></q-banner>
        </q-popup-edit>
      </q-btn>
    </q-toolbar>

    <div
      class="resource-store-box"
      @dragover="handleDragOver"
      @dragleave="handleDragLeave"
      @drop="handleDrop"
      id="drop-area"
      :style="{
        height: `${$q.screen.height - 50 - 50 - 21}px`,
        overflow: 'auto',
      }"
    >
      <q-list
        padding
        class="rounded-borders"
        style="max-width: 100%; height: 100%"
      >
        <q-item-label header>文件夹</q-item-label>

        <q-item
          clickable
          v-ripple
          v-for="item in resource.dir"
          :key="item.id"
          @click="IntoResource(item)"
          @mouseenter="handleMouseEnter(item.id)"
          @mouseleave="handleMouseLeave"
        >
          <q-item-section avatar top>
            <q-avatar icon="folder" color="primary" text-color="white" />
          </q-item-section>

          <q-item-section>
            <q-item-label lines="1">{{ item.name }}</q-item-label>
            <q-item-label caption>更新时间：{{ item.updateTime }}</q-item-label>
          </q-item-section>

          <q-item-section side v-if="hoveredItem === item.id">
            <div class="row">
              <q-btn
                flat
                dense
                round
                icon="fa-solid fa-gear"
                color="grey-7"
                @click.stop="DisplaySettingsForDir(item)"
              />
            </div>
          </q-item-section>
        </q-item>

        <q-item-label header>文件</q-item-label>

        <q-item
          clickable
          v-ripple
          v-for="item in resource.file"
          :key="item.id"
          @mouseenter="handleMouseEnter(item.id)"
          @mouseleave="handleMouseLeave"
          @dblclick="ShowDialog(item)"
        >
          <q-item-section avatar top>
            <q-avatar icon="assignment" color="grey" text-color="white" />
          </q-item-section>

          <q-item-section>
            <q-item-label lines="1">{{ item.name }}</q-item-label>
            <q-item-label caption
              >更新时间：{{ item.updateTime }}, 大小：{{
                item.size / 1024
              }}KB，MD5：{{ item.md5 }}</q-item-label
            >
          </q-item-section>

          <q-item-section side v-if="hoveredItem === item.id">
            <div class="row">
              <q-btn
                flat
                dense
                round
                size="10px"
                icon="fa-solid fa-blog"
                :href="origin + '/#/application/blog?ResourceId=' + item.id"
                target="_blank"
                color="teal"
                v-if="item.name.endsWith('.blog.md')"
              />

              <q-btn
                flat
                dense
                round
                icon="download"
                :href="
                  publicPath + item.downloadPath + '?token=' + resourceToken
                "
                target="_blank"
                color="primary"
              />
              <q-btn
                flat
                dense
                round
                icon="fa-solid fa-square-minus"
                color="red-4"
                @click="RemoveResource(item.id)"
              />
            </div>
          </q-item-section>
        </q-item>
      </q-list>

      <q-dialog
        v-model="dialog"
        persistent
        :maximized="maximizedToggle"
        transition-show="slide-up"
        transition-hide="slide-down"
      >
        <q-card class="bg-primary text-white" style="min-width: 500px">
          <q-bar>
            {{ selectDir.name }}
            <q-space />

            <q-btn
              dense
              flat
              icon="fa-regular fa-circle-question"
              @click="OpenDirHelper"
            >
              <q-tooltip class="bg-white text-primary">帮助</q-tooltip>
            </q-btn>

            <q-btn
              dense
              flat
              icon="minimize"
              @click="maximizedToggle = false"
              :disable="!maximizedToggle"
            >
              <q-tooltip v-if="maximizedToggle" class="bg-white text-primary"
                >Minimize</q-tooltip
              >
            </q-btn>
            <q-btn
              dense
              flat
              icon="crop_square"
              @click="maximizedToggle = true"
              :disable="maximizedToggle"
            >
              <q-tooltip v-if="!maximizedToggle" class="bg-white text-primary"
                >Maximize</q-tooltip
              >
            </q-btn>
            <q-btn dense flat icon="close" v-close-popup>
              <q-tooltip class="bg-white text-primary">Close</q-tooltip>
            </q-btn>
          </q-bar>

          <q-card-section style="max-width: 500px">
            <div class="text-h6" style="margin-bottom: 10px">图床设置</div>
            <div class="row">
              <q-btn label="生成APIKEY" class="col" @click="SetImageLink" />
              <q-btn label="关闭该功能" class="col" @click="DeleteImageLink" />
            </div>
            <div class="row">
              <q-input
                v-if="selectDir.apiKey"
                readonly
                label="API KEY"
                :model-value="selectDir.apiKey"
                class="col-12"
              >
                <template #append>
                  <q-btn
                    flat
                    dens
                    rounded
                    icon="fa-solid fa-copy"
                    @click="
                      () => {
                        copyToClipboard(selectDir.apiKey);
                      }
                    "
                  />
                </template>
              </q-input>
              <q-input
                v-if="selectDir.apiKey"
                readonly
                label="BaseUrl"
                class="col-12"
                :model-value="`/image/${userInfo.username}/${selectDir.name}`"
              >
                <template #append>
                  <q-btn
                    flat
                    dens
                    rounded
                    icon="fa-solid fa-copy"
                    @click="
                      () => {
                        copyToClipboard(
                          `/image/${userInfo.username}/${selectDir.name}`,
                        );
                      }
                    "
                  />
                </template>
              </q-input>
            </div>
            <div class="row"></div>
          </q-card-section>

          <q-card-section style="max-width: 500px">
            <div class="text-h6" style="margin-bottom: 10px">其他设置</div>
            <div class="row">
              <q-btn
                label="删除文件夹"
                color="red-4"
                class="col"
                @click="RemoveResource(selectDir.id)"
              />
            </div>
          </q-card-section>

          <q-inner-loading :showing="imgLinkVisible">
            <q-spinner-gears size="20px" color="primary" />
          </q-inner-loading>
        </q-card>
      </q-dialog>

      <q-dialog
        v-model="dialogFile"
        persistent
        :maximized="true"
        transition-show="slide-down"
        transition-hide="slide-up"
      >
        <q-card class="bg-primary text-white" style="min-width: 500px">
          <q-bar>
            {{ previewTitle }}
            <q-space />

            <q-btn dense flat icon="close" v-close-popup>
              <q-tooltip class="bg-white text-primary">Close</q-tooltip>
            </q-btn>
          </q-bar>
          <q-card-section
            style="min-width: 500px; min-height: 400px; height: 97%"
          >
            <iframe height="100%" width="100%" :src="previewFileUrl" />
          </q-card-section>
        </q-card>
      </q-dialog>
    </div>
  </q-page>
</template>

<script setup>
import { ref, reactive, onMounted, watch } from "vue";
import URLSearch from "src/utility/URLSearch";
import { api, session, basePath } from "src/boot/axios";
import { useQuasar, copyToClipboard } from "quasar";
import notify from "src/utility/notify";

const dialog = ref(false);
const maximizedToggle = ref(false);
const selectDir = ref(null);
const imgLinkVisible = ref(false);

const dialogFile = ref(false);
const origin = location.origin;
const publicPath =
  process.env.NODE_ENV === "production"
    ? location.origin
    : "http://127.0.0.1:5000";
const resourcePath = reactive({
  path: [],
  resourceId: null,
});
const isLoading = ref(false);
const $q = useQuasar();
const resourceToken = ref(null);
const resource = reactive({
  dir: [],
  file: [],
});
const RefreshBtnRef = ref(null);
watch(resourcePath, () => {
  if (resourcePath.resourceId) {
    URLSearch.addOrUpdateQueryParam("ResourceId", resourcePath.resourceId);
  } else {
    URLSearch.deleteQueryParam("ResourceId");
  }
});

const OpenDirHelper = () => {
  previewTitle.value = "文件夹帮助";
  dialogFile.value = true;
  const fileUrl = location.origin + "/assets/文件夹功能快速入门.html";
  previewFileUrl.value = fileUrl;
};

const previewTitle = ref("文件预览");
const previewFileUrl = ref("");
const ShowDialog = (item) => {
  dialogFile.value = true;
  previewTitle.value = item.name;
  // https://www.wgeco.cn/filepreview/onlinePreview?url=aHR0cDovL2xvY2FsaG9zdDo1MDAwL2ltYWdlL2N6aHUvaWNvbi9uZ2lueC5pY28=
  const fileUrl =
    publicPath +
    item.downloadPath +
    "/" +
    resourceToken.value +
    "/" +
    encodeURIComponent(item.name);
  console.log(fileUrl);
  previewFileUrl.value =
    `https://www.wgeco.cn/filepreview/onlinePreview?url=` + btoa(fileUrl);
};

const DisplaySettingsForDir = async (item) => {
  imgLinkVisible.value = true;
  selectDir.value = item;
  dialog.value = true;
  try {
    const response = (await api.get(`${publicPath}/image/${item.id}`)).data;
    selectDir.value.apiKey = response.apiKey;
  } catch (ex) {
    if (ex.response !== undefined && ex.response.data.message) {
      notify.warn(ex.response.data.message);
    } else {
      notify.error(`获取图床信息失败: ` + ex.message);
      console.error(ex);
    }
    dialog.value = false;
  } finally {
    imgLinkVisible.value = false;
  }
};

const SetImageLink = async () => {
  imgLinkVisible.value = true;
  try {
    const response = (
      await api.post(`${publicPath}/image/${selectDir.value.id}`)
    ).data;
    notify.success(response.message);
    DisplaySettingsForDir(selectDir.value);
  } catch (ex) {
    if (ex.response !== undefined && ex.response.data.message) {
      notify.warn(ex.response.data.message);
    } else {
      notify.error(`设置图床信息失败: ` + ex.message);
      console.error(ex);
    }
  } finally {
    imgLinkVisible.value = false;
  }
};

const DeleteImageLink = async () => {
  imgLinkVisible.value = true;
  try {
    const response = (
      await api.delete(`${publicPath}/image/${selectDir.value.id}`)
    ).data;
    notify.success(response.message);
    DisplaySettingsForDir(selectDir.value);
  } catch (ex) {
    if (ex.response !== undefined && ex.response.data.message) {
      notify.warn(ex.response.data.message);
    } else {
      notify.error(`设置图床信息失败: ` + ex.message);
      console.error(ex);
    }
  } finally {
    imgLinkVisible.value = false;
  }
};

const hoveredItem = ref(null);
function handleMouseEnter(itemId) {
  setTimeout(() => {
    hoveredItem.value = itemId; // Set the hoveredItem to be the current item's id
  }, 100);
}
function handleMouseLeave() {
  setTimeout(() => {
    hoveredItem.value = null; // Reset hoveredItem when the mouse leaves
  }, 50);
}

const IntoResource = async (res) => {
  resourcePath.resourceId = res.id;
  getResource();
};

const CreateFile = async (files, scope = null) => {
  if (files.length === 0) {
    notify.warn("请选择上传的资源！");
    return;
  }
  let p = resourcePath.resourceId;
  if (!p) p = "";
  const file = files[0];
  const filename = file.name;
  isLoading.value = true;
  const formData = new FormData();
  formData.append("file", file);
  if (scope) {
    scope.set();
  }
  notify.info("已经在后台上传，请勿离开该页面！");
  try {
    const response = (
      await api.post(`/cloud/?p=${p}&n=${filename}&t=file`, formData, {
        headers: {
          "Content-Type": "multipart/form-data",
        },
      })
    ).data;
    notify.success(response.message);
  } catch (ex) {
    if (ex.response !== undefined && ex.response.data.message) {
      notify.warn(ex.response.data.message);
    } else {
      notify.error(`上传文件失败: ` + ex.message);
      console.error(ex);
    }
  } finally {
    isLoading.value = false;
  }
  RefreshBtnRef.value.click();
};

const handleDragOver = (event) => {
  event.preventDefault();
  const dropArea = document.getElementById("drop-area");
  dropArea.classList.add("highlight");
};

const handleDragLeave = () => {
  const dropArea = document.getElementById("drop-area");
  dropArea.classList.remove("highlight");
};

const handleDrop = async (event) => {
  event.preventDefault();
  const dropArea = document.getElementById("drop-area");
  dropArea.classList.remove("highlight");
  const files = event.dataTransfer.files;
  if (files.length) {
    CreateFile(files);
  }
};

const CreateBlog = async (scope) => {
  const name = scope.value;
  let p = resourcePath.resourceId;
  if (!p) p = "";
  isLoading.value = true;
  try {
    const response = (await api.post(`/blog/?p=${p}&n=${name}`)).data;
    notify.success(response.message);
    window.open(
      location.origin + "/#/application/blog?ResourceId=" + response.data,
    );
  } catch (ex) {
    if (ex.response !== undefined && ex.response.data.message) {
      notify.warn(ex.response.data.message);
    } else {
      notify.error(`创建博客失败: ` + ex.message);
      console.error(ex);
    }
  } finally {
    isLoading.value = false;
  }

  scope.set();
  RefreshBtnRef.value.click();
};

const CreateDir = async (scope) => {
  const dirName = scope.value;
  let p = resourcePath.resourceId;
  if (!p) p = "";
  isLoading.value = true;
  try {
    const response = (await api.post(`/cloud/?p=${p}&n=${dirName}&t=dir`)).data;
    notify.success(response.message);
  } catch (ex) {
    if (ex.response !== undefined && ex.response.data.message) {
      notify.warn(ex.response.data.message);
    } else {
      notify.error(`创建文件夹失败: ` + ex.message);
      console.error(ex);
    }
  } finally {
    isLoading.value = false;
  }

  scope.set();
  RefreshBtnRef.value.click();
};

const RemoveResource = (id) => {
  $q.notify({
    message: "是否要永久删除该资源.",
    color: "red",
    actions: [
      {
        label: "删除",
        color: "yellow",
        handler: async () => {
          imgLinkVisible.value = true;
          $q.loading.show();

          try {
            const response = (await api.delete(`/cloud/?r=${id}`)).data;
            notify.success(response.message);
            await getResource();
          } catch (ex) {
            if (ex.response !== undefined && ex.response.data.message) {
              notify.warn(ex.response.data.message);
            } else {
              notify.error(`删除资源失败: ` + ex.message);
              console.error(ex);
            }
          } finally {
            imgLinkVisible.value = false;
            dialog.value = false;
            $q.loading.hide();
          }
        },
      },
      {
        label: "取消",
        color: "white",
        handler: () => {
          /* ... */
        },
      },
    ],
  });
};

const getResource = async () => {
  isLoading.value = true;
  let resourceId = resourcePath.resourceId;
  if (!resourceId) resourceId = "";
  try {
    const response = (await api.get("/cloud/?resource_id=" + resourceId)).data;
    resourceToken.value = response.token;
    resourcePath.path = response.path;
    if (Object.keys(response.items).includes("dir")) {
      resource.dir = response.items.dir;
    } else {
      resource.dir = [];
    }
    if (Object.keys(response.items).includes("file")) {
      resource.file = response.items.file;
    } else {
      resource.file = [];
    }

    if (response.dir) {
      resourcePath.resourceId = response.dir.id;
    } else {
      resourcePath.resourceId = null;
    }

    resourcePath.path = response.path;
  } catch (ex) {
    if (ex.response !== undefined && ex.response.data.message) {
      notify.warn(ex.response.data.message);
    } else {
      notify.error(`获取资源失败: ` + ex.message);
      console.error(ex);
    }
    resourcePath.resourceId = null;
  } finally {
    isLoading.value = false;
  }
};

const reload = async () => {
  await getResource();
};

const onloadPageInfo = async () => {
  const params = URLSearch.getAllQueryParams();
  if (params && params.ResourceId) {
    resourcePath.resourceId = params.ResourceId;
    console.log("Get Resource id:", resource.id);
  }
  await getResource();
};

const userInfo = ref(null);

onMounted(async () => {
  $q.loading.show();

  userInfo.value = await session.get("userInfo");
  if (userInfo.value !== null) {
    await onloadPageInfo();
  }
  $q.loading.hide();
});
</script>

<style>
.resource-store-box {
  height: calc(100% - 50px);
  margin-top: 50px;
  color: #0d0d0d;
  width: 100%;
}

.clickable {
  cursor: pointer;
}

.clickable:hover {
  font-weight: 700;
}

.hidden {
  display: none;
}

#drop-area.highlight {
  border: 1px solid #0d0d0d;
  border-radius: 15px;
  background-color: azure;
  border-color: #333;
}
</style>
